use-propagate
Propagates a value to multiple nodes via callback function using React context and hooks.
Background
This pattern is useful for triggering multiple nodes via callback function.
Unlike setting a value in a context, invoking a callback function will not trigger re-render. Subscribers can choose to save the value into its state and re-render as needed.
How to use
Live demo
The following code snippet sends the focus to the text box when the button is tapped.
import { createPropagation } from 'use-propagate';
const { Provider, useListen, usePropagate } = createPropagation<void>();
const FocusButton = () => {
const propagate = usePropagate();
const handleClick = useCallback(() => propagate(), [propagate]);
return (
<button autoFocus={true} onClick={handleClick}>
Tap to focus to the text box
</button>
);
};
const TextBox = () => {
const ref = useRef<HTMLInputElement>(null);
const handleListen = useCallback(() => ref.current?.focus(), [ref]);
useListen(handleListen);
return <input ref={ref} type="text" />;
};
render(
<Provider>
<FocusButton />
<TextBox />
</Provider>
);
API
export function createPropagation<T>(): {
Provider: ComponentType<{ children?: ReactNode | undefined }>;
useListen: (callback: (value: T) => void) => void;
usePropagate: (value: T) => void;
};
Behaviors
Why not passing values via useContext
?
When propagating a value via useContext
, subscribing nodes will be re-rendered. This behavior may not be desirable for events and certain type of scenarios.
How to get response from the listener or wait for the listener to complete?
Modifies the passing value by following the FetchEvent.respondWith
pattern or ExtendableEvent.waitUntil
pattern.
How to re-render when triggered?
Use the following code snippet to save the value to a state, which will cause a re-render.
const MyComponent = () => {
const [value, setValue] = useState();
useListen(value => setValue(value));
return (<p>The value is {value}</p>.
};
Contributions
Like us? Star us.
Want to make it better? File us an issue.
Don't like something you see? Submit a pull request.